/************************************************************************
 *                           cEdit_interface.c
 *                           by Scott J. Pearson
 * This file contains methods which provide the interface for cloneedit.
 * Also, input and output methods are placed in this file. Helper methods
 * are included.
 */

#include <stdio.h>
#include <gtk/gtk.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#include "fpp.h"
#include "float.h"
#include "gtkhelp.h"
#include "cEdit.h"

#define BORDER_WIDTH 7

void input_data(CLONE* cl, int cloneindex);
int output_data(CLONE* cl);
void create_mainWindow(CLONE *currclone, int cloneindex);
void append_attached_remarks(GtkWidget* t, char* c);

void appendMarkerToList(int markerindex);

int findBuriedClones(int parentindex, struct CharList** CL);

extern void zero_left_end(int ctg);
extern void on_Window_delete();
extern void on_RenameButton_clicked(GtkWidget* CI);
extern void on_Rename_Accept_clicked (GtkWidget* CI, GtkWidget* CE);
extern void on_Dialog_delete(GtkWidget* CI);
extern void on_CancelButton_clicked(GtkWidget* CI, CLONE* cl);
extern void on_ShotgunStatusMenuItem_activate(GtkWidget* CI, GtkWidget* OOM);
extern void CreateDialog();
extern void on_AcceptButton_clicked(GtkWidget* CI, CLONE* cl);
extern void on_RejectButton_clicked(GtkWidget* CI);
extern void on_HelpButton_clicked(GtkWidget* CI);
extern void on_MarkersPickToggle_toggled(GtkWidget* CI, GtkWidget* Txt);
extern void on_BuriedClonesPickToggle_toggled(GtkWidget* CI, GtkWidget* Txt);
extern void detach_marker_from_clone(int marker_index, int clone_index);
extern void update_contigs_list(int marker_index);

extern void removeCloneFromMarkersList(int cloneindex,int markerindex);
extern void markersinctgcount();
extern void gtk_ctgdisplay(int ctg);
extern void set_marker_clone_max();

extern BOOL bury(int c1,int c2);
extern BOOL unbury(int c1);
extern BOOL checkokaytobury(int c1, int c2);
extern void settime(struct mytime *mytime);
extern void sortoutmarkerindex(void);
extern void refreshlist();

extern void attach_marker_to_clone(int clone_index, int marker_index);
extern int attach_clone_to_marker(int marker_index, int clone_index);

extern void setmarkerposctg();

extern void move_selected(int from,int result,int distance);

extern int calcmarkerctgpos(struct markerctgpos *pos, int markerindex);
extern void destroy_edit_clone_callback(GtkWidget *widget, gpointer data);

void update_ctg_marker_count(int ctg);
void add_marker_by_name(char* mrkname, int clone_idx);

extern int ZincrFlag;
extern int called_by_merge;

extern GtkWidget* markerEditWindow;

CLONE* clone_edit_clone;


void unbury_if_needed(int idx)
{
    CLONE* cl = arrp(acedata, idx, CLONE);
    if (cl->parent > -1 )
    {
        unbury(idx);
    }
}

/* finds the buried clones of clone parentindex
 * returns places them in CL, and returns their number as an int
 * CL will be allocated internally
*/
int findBuriedClones(int parentindex, struct CharList** CL)
{
   int numElems;
   int i;
   CLONE* currclone;
   struct CharList* currCharList;

   numElems = 0;
   *CL = (struct CharList*) malloc(sizeof(struct CharList));
   currCharList = *CL;
   for (i = 0; i < arrayMax(acedata); i++)
   {
      currclone = arrp(acedata, i, CLONE);
      if (currclone->parent == parentindex)
      {
         numElems++;
         sprintf(currCharList->name, "%s", currclone->clone);
         currCharList->next = (struct CharList*) malloc(sizeof(struct CharList));
         currCharList = currCharList->next;
         currCharList->next = NULL;
      }
   }

   if (numElems == 0)
   {
      free(*CL);
      *CL = NULL;
   }

   return numElems;
}

void input_data(CLONE *clone, int cloneindex)
{
   int i;
   CONTIGDATA* ctg = NULL;
   struct markertop* currMarker1;
   struct markertop** currMarker2;

   memcpy(&localcl, clone, sizeof(CLONE));
   localcl.fp = (struct fpdata*) malloc (sizeof(struct fpdata));
   memcpy(localcl.fp, clone->fp, sizeof(struct fpdata));
   for (currMarker1 = clone->marker, currMarker2 = &localcl.marker;
        currMarker1 != NULL;
        currMarker1 = currMarker1->nextmarker,
                    currMarker2 = &((*currMarker2)->nextmarker))
   {
      *currMarker2 = (struct markertop*) malloc(sizeof(struct markertop));
      memcpy(*currMarker2, currMarker1, sizeof(struct markertop));
   }

   if (!fppFind(acedata, localcl.clone, &localmisc.cloneindex, cloneOrder))
   {
      printf("ERROR: Cannot find cloneindex for clone %s\n", localcl.clone);
   }

   localmisc.NumBuriedClones =
                 findBuriedClones(localmisc.cloneindex, &localmisc.BuriedClones);
   localmisc.NumCtgsInGenome = max_contig + 1;
                         // + 1 allows a new contig to be created

   if (localcl.ctg > 0)
   {
      for (i = 1; i <= max_contig; i++)
      {
         if (contigs[i].ctg == localcl.ctg)
         {
            ctg = &contigs[i];
            break;
         }
      }
      if (ctg != NULL)
      {
         localmisc.ContigL = ctg->left;
         localmisc.ContigR = ctg->right;
      }
   }
}

/* Determine if a string has any non-whitespace content*/
int is_empty(char* str)
{
    char* ptr = str;
    if (!str)
    {
        return 1;
    }
    while (*ptr)
    {
        if (!isspace(*ptr))
        {
            return 0;
        }
        ptr++;
    }
    return 1;
}
int contains_whitespace(char* str)
{
    char* ptr = str;
    if (!str)
    {
        return 0;
    }
    while (*ptr)
    {
        if (isspace(*ptr))
        {
            return 1;
        }
        ptr++;
    }
    return 0;
}

/* copy num chars and put a zero AFTER the last one */
void safe_strncpy(char* dest, char* src, size_t num)
{
    strncpy(dest,src,num);
    dest[num] = 0;   
}

void add_remarks(char* rmk_string, struct remark** pp_next_rmk)
{
    char* ptr;

    *pp_next_rmk = 0;
    if (is_empty(rmk_string))
    {
        return;
    }


    ptr = strtok(rmk_string,"\n");
    if (!is_empty(ptr))
    {
        *pp_next_rmk = (struct remark*)malloc(sizeof(struct remark));
        safe_strncpy((*pp_next_rmk)->message, ptr, COMMENT_SZ);
        (*pp_next_rmk)->next = 0;      
        pp_next_rmk = &((*pp_next_rmk)->next);  
    }
    while ((ptr = strtok(0,"\n")))
    {
        if (!is_empty(ptr))
        {
            *pp_next_rmk = (struct remark*)malloc(sizeof(struct remark));
            safe_strncpy((*pp_next_rmk)->message, ptr, COMMENT_SZ);
            (*pp_next_rmk)->next = 0;           
            pp_next_rmk = &((*pp_next_rmk)->next);   
        }
    } 
}

void uppercase(char* str)
{
    unsigned char* p = (unsigned char*)str;
    while (*p)
    {
        *p = toupper(*p);
        p++;
    }
}

int is_parent (CLONE* clp, int idx)
{
    int ret = 0;
    int c;
    CLONE* clp2;
    int i;

    if (clp->ctg > 0)
    {
        c =  contigs[clp->ctg].start;
        for (i = 0; i < contigs[clp->ctg].count && c != -1; i++)
        {
            clp2 = arrp(acedata, c, CLONE);
            if (clp2->parent == idx)
            {
                ret = 1;
                break;
            }
            c= clp2->next;
        } 
    }
    return ret;
}

/* Search a \n-delimited list for the query string (case-insensitive) */
int is_in_list(char* list, char* query)
{
    char* strtok_tmp = 0;
    char* ptr;
    int ret = 0;

    if (!is_empty(list))
    {
        strtok_tmp = strdup(list);
        ptr = strtok(strtok_tmp,"\n");
        if (!is_empty(ptr))
        {
            if (!strcasecmp(ptr,query))
            {
                ret = 1;
            }
        }
        while (ret == 0 && (ptr = strtok(0,"\n")))
        {
            if (!strcasecmp(ptr, query))
            {
                ret = 1;
            }
        }
    }
    return ret;
}

/* rewritten by WN 5/04 */
/* return 0 if data is invalid */
/* some parsing is done with the wretched strtok, which
    has side effects on the string being parsed */
int output_data(CLONE* clone)
{
    gchar* gstr1;
    GtkWidget* item;
    int i;
    CLONE* parent;
    int parentindex = 0;
    int bcloneindex, markerindex;
    CLONE* clp;
    char str[150];
    gchar* gstr_parent;
    gchar* gstr_buried;
    gchar* gstr_remark;
    gchar* gstr_fp;
    gchar* gstr_mrk;
    gchar* gstr_name;
    char* ptr;
    int new_ctg;
    int move_buried = 0;
    int new_x, new_y;
    int c;
    char* strtok_tmp = 0;
    int do_move = 0;
    int found_one;
    struct markertop* next_mrk;
    GtkTextIter it1;
    GtkTextIter it2;
    GtkTextBuffer* buffer;

    /* first we will get and validate all the data */

    new_ctg = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(mw.Contig));
    gstr_parent = (gchar*)gtk_entry_get_text(GTK_ENTRY(mw.ParentText));

    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mw.BuriedClonesTextView));
    gtk_text_buffer_get_bounds(buffer,&it1,&it2);
    gstr_buried = (gchar*)gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE);

    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mw.RemarksTextView));
    gtk_text_buffer_get_bounds(buffer,&it1,&it2);
    gstr_remark = (gchar*)gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE);

    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mw.FpRemarksTextView));
    gtk_text_buffer_get_bounds(buffer,&it1,&it2);
    gstr_fp = (gchar*)gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE);

    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(mw.MarkersTextView));
    gtk_text_buffer_get_bounds(buffer,&it1,&it2);
    gstr_mrk = (gchar*)gtk_text_buffer_get_text(buffer,&it1,&it2,TRUE);

    gtk_label_get(GTK_LABEL(mw.CloneName), &gstr_name); 

    /* Get and check the endpoints; note these entries will be absent for singletons,
        which we will always start at 0 */
    new_x = 0;
    new_y = clone->fp->b2;
    if (mw.CloneContigL)
    {
        gstr1 = (gchar*)gtk_entry_get_text(GTK_ENTRY(mw.CloneContigL));
        new_x= atoi(gstr1);
        gstr1 = (gchar*)gtk_entry_get_text(GTK_ENTRY(mw.CloneContigR));
        new_y = atoi(gstr1);
        if (new_y <= new_x)
        {
            CreateDialog("The right coordinate must be greater than the left!");
            return 0;
        }
        else if ((new_x != clone->x || new_y != clone->y) && new_y - new_x + 1 != clone->fp->b2)
        {
            if (!messQuery("The new coordinates do not agree with the band count. Proceed anyway?"))
            {
                return 0;
            }
        }
    }

    /* Check whether a move is really being done. A move is not done if the only
        thing changing is x,y and the ctg = 0. In this case the x,y change is
        only due to the defaults we used for new_x,new_y anyway */
    if (new_ctg != clone->ctg || 
                (clone->ctg > 0 && (new_x != clone->x || new_y != clone->y)) )
    {
        do_move = 1;
    }

   /* validate parent */
    if ((gstr_parent != NULL) && (strlen(gstr_parent) > 0))
    {
        if (fppFind(acedata, gstr_parent, &parentindex, cloneOrder))
        {
            /* Grandparents are not allowed */
            parent = arrp(acedata, parentindex, CLONE);
            if (parent->ctg != clone->ctg)
            {
                CreateDialog("The specified parent can not be used because it is in a different contig.");
                return 0;
            }
            if (parentindex == localmisc.cloneindex)
            {
                CreateDialog("The parent is the same as the clone.");
                return 0;
            }
            if (parent->ctg == 0)
            {
                CreateDialog("The specified parent can not be used because it is a singleton.");
                return 0;
            }
            if (parent->parent > -1)
            {
                CreateDialog("The specified parent can not be used because it is buried.");
                return 0;
            }
            if (!is_empty(gstr_buried))
            {
                CreateDialog("The clone can not have both parent and buried clones.");
                return 0;
            }   
            if (do_move)  
            {
                sprintf(str,"The clone can not be moved while it is buried. It may be unburied first, or its parent may be moved.");
                CreateDialog(str);
                return 0; 
            }     
        }
        else  
        {
            CreateDialog("The specified parent does not exist.");
            return 0;
        }
    }


    /* if the buried list is not empty check it */
    if (!is_empty(gstr_buried))
    {
        /* check that given clone is not in contig 0 */
        if (clone->ctg == 0)
        {   
            sprintf(str,"This clone is a singleton and cannot have buried clones.\n");
            CreateDialog(str);
            return 0; 
        } 

        /* Check that all buried clones exist, are in the same contig, and are not parents */
        strtok_tmp = strdup(gstr_buried);
        ptr = strtok(strtok_tmp,"\n");
        if (!fppFind(acedata, ptr, &bcloneindex, cloneOrder))
        {   
            sprintf(str,"Clone %s in the buried list does not exist.",ptr);
            CreateDialog(str);
            return 0; 
        }  
        if (bcloneindex == localmisc.cloneindex)
        {   
            sprintf(str,"The clone cannot be buried in itself.");
            CreateDialog(str);
            return 0; 
        }  
        clp = arrp(acedata, bcloneindex, CLONE); 
        if (clp->ctg != clone->ctg)
        {   
            sprintf(str,"Clone %s in the buried list is not in contig %d.",ptr,clone->ctg);
            CreateDialog(str);
            return 0; 
        }   
        if (is_parent(clp, bcloneindex))
        {   
            sprintf(str,"Clone %s in the buried list is a parent.",clp->clone);
            CreateDialog(str);
            return 0; 
        }   
        while ((ptr = strtok(0,"\n"))) 
        {
            if (!fppFind(acedata, ptr, &bcloneindex, cloneOrder))
            {   
                sprintf(str,"Clone %s in the buried list does not exist.",ptr);
                CreateDialog(str);
                return 0; 
            }      
            if (bcloneindex == localmisc.cloneindex)
            {   
                sprintf(str,"The clone cannot be buried in itself.");
                CreateDialog(str);
                return 0; 
            }  
            clp = arrp(acedata, bcloneindex, CLONE); 
            if (clp->ctg != clone->ctg)
            {   
                sprintf(str,"Clone %s in the buried list is not in contig %d.",ptr,clone->ctg);
                CreateDialog(str);
                return 0; 
            }   
            if (is_parent(clp,bcloneindex))
            {   
                sprintf(str,"Clone %s in the buried list is a parent.",clp->clone);
                CreateDialog(str);
                return 0; 
            }      
        } 

    }

    /* If they are moving the clone to a different contig, find out
        if they want to move the buried clones too */

    move_buried = 0;
    if (do_move)
    {
        if (!is_empty(gstr_buried))
        {
            if (new_ctg > 0)
            {
                sprintf(str,"Do you want to move the buried clones also? If not,they will be unburied");
            }
            else
            {
                sprintf(str,"Do you want to move the buried clones to contig 0 also? (In either case, they will be unburied.)");
            }
            if(messQuery(str))
            {
                move_buried = 1;
            }
        }
    }

    /* Check that all markers have valid names.
        Also verify that they want to add new markers if any. */
    if (!is_empty(gstr_mrk))
    {
        strtok_tmp = strdup(gstr_mrk);
        ptr = strtok(strtok_tmp,"\n");
        if (!is_empty(ptr))
        {
            if (strlen(ptr) >= MARKER_SZ)
            {   
                sprintf(str,"Marker %s has a name that is too long.",ptr);
                CreateDialog(str);
                return 0; 
            }   
            if (contains_whitespace(ptr))
            {
                sprintf(str,"Marker \"%s\" has spaces in its name.",ptr);
                CreateDialog(str);
                return 0; 
            }            
            if(!fppFind(markerdata, ptr, &markerindex, markerOrder))
            {
                if (!messQuery("Marker %s appears to be a new marker; would you like to add it to this clone?"))
                {
                    return 0;
                }
            }

        }
        while ((ptr = strtok(0,"\n")))
        {
            if (is_empty(ptr))
            {
                continue;
            }
            if (strlen(ptr) >= MARKER_SZ)
            {   
                sprintf(str,"Marker %s has a name that is too long.",ptr);
                CreateDialog(str);
                return 0; 
            }     
            if (contains_whitespace(ptr))
            {
                sprintf(str,"Marker \"%s\" has spaces in its name.",ptr);
                CreateDialog(str);
                return 0; 
            }                
            if(!fppFind(markerdata, ptr, &markerindex, markerOrder))
            {
                if (!messQuery("Marker %s appears to be a new marker; would you like to add it to this clone?"))
                {
                    return 0;
                }
            }

        }
    }


    /* Now the data should be ok. We can put it in. */
    
    update = 1;

    /* First unbury this clone if the new parent is different from the 
        old one */
    if (clone->parent != -1 && parentindex != clone->parent)
    {
        unbury(localmisc.cloneindex);
    }

    /* Now unbury the clones currently buried in this clone which are not in the 
        bury list */

    c =  contigs[clone->ctg].start;
    for (i = 0; i < contigs[clone->ctg].count && c != -1; i++)
    {
        clp = arrp(acedata, c, CLONE);
        if (clp->parent == localmisc.cloneindex && 
            !is_in_list(gstr_buried, clp->clone))
        {
            unbury(c);
        }
        c= clp->next;
    } 

    /* Apply the new parent, or buried clones */
    if (parentindex > 0 && parentindex != clone->parent)
    {
        bury(localmisc.cloneindex,parentindex);
    }
    else if (!is_empty(gstr_buried))
    {
        ptr = strtok(gstr_buried,"\n");
        fppFind(acedata, ptr, &bcloneindex, cloneOrder);
        clp = arrp(acedata, bcloneindex, CLONE);
        if (clp->parent != localmisc.cloneindex)
        {
            bury(bcloneindex,localmisc.cloneindex);
        }
        while ((ptr = strtok(0,"\n")))
        {
            fppFind(acedata, ptr, &bcloneindex, cloneOrder);
            clp = arrp(acedata, bcloneindex, CLONE);
            if (clp->parent != localmisc.cloneindex)
            {
                bury(bcloneindex,localmisc.cloneindex);
            }
        } 
    }
   


    /* Set the various types*/

    item = gtk_menu_get_active(GTK_MENU(mw.CloneTypeMenu));
    for (i = 0; i <= clonetypenum; i++) 
    {
      if (mw.CloneTypeMIAry[i] == item)
      {
         clone->class = i;
         break;
      }
    }

    item = gtk_menu_get_active(GTK_MENU(mw.ShotgunTypeMenu));
    for (i = 0; i < seqstatnum; i++) 
    {
      if (mw.ShotgunTypeMIAry[i] == item)
      {
         clone->seqtype = i;
         break;
      }
    }

    item = gtk_menu_get_active(GTK_MENU(mw.StatusMenu));
    for (i = 0; i < seqstatnum; i++) 
    {
      if (mw.StatusMIAry[i] == item)
      {
         clone->seqstat = i;
         break;
      }
    }

    /* Now remove all the markers from the clone, which aren't on the list.
        Note that we can't just  remove them all, then add back the ones on
        the list, because a marker may get entirely deleted and have its 
        remarks cleared. */

    do
    {
        next_mrk = clone->marker;
        found_one = 0;

        /* every time we remove a marker from the list, we have to start
                again going through it */

        while (next_mrk)
        {
            if (!is_in_list(gstr_mrk, next_mrk->marker))
            {
                found_one = 1;
                markerindex = next_mrk->markerindex;
                detach_marker_from_clone(markerindex, localmisc.cloneindex); 
                removeCloneFromMarkersList(localmisc.cloneindex, markerindex);
                update_contigs_list(markerindex); 
                break;
            }
            next_mrk = next_mrk->nextmarker;
        }  
    } while (found_one); 

    /* Now add the markers from the list. The function used 
        does not re-add markers that already are added. */
    
    if (!is_empty(gstr_mrk))
    {
        ptr = strtok(gstr_mrk,"\n");
        if (ptr && !is_empty(ptr))
        {
            add_marker_by_name(ptr,localmisc.cloneindex);
        }
        while ((ptr = strtok(0,"\n")))
        {
            if (ptr && !is_empty(ptr))
            {
                add_marker_by_name(ptr,localmisc.cloneindex);
            }
        }
    }

    rootmarkerptr = 0;

    sortoutmarkerindex();
    markersinctgcount();
    setmarkerposctg();
    
    add_remarks(gstr_remark, &clone->remark); 
    add_remarks(gstr_fp, &clone->fp_remark); 

    /* Finally we do the move. Note that if the only thing changing is position,
        and ctg = 0, then there is no move (because pos. only was changed by our
        defaults for new_x, new_y) */

    if (new_ctg != clone->ctg || 
                (clone->ctg > 0 && (new_x != clone->x || new_y != clone->y)) )
    {
        /* First must make only the one clone selected,
        and unbury its kids if they are not going to be moved */
        c =  contigs[clone->ctg].start;
        for (i = 0; i < contigs[clone->ctg].count && c != -1; i++)
        {
            clp = arrp(acedata, c, CLONE);
            clp->selected = FALSE;
            if (c == localmisc.cloneindex )
            {
                clp->selected = TRUE;
            }
            else if (!move_buried && clp->parent == localmisc.cloneindex)
            {
                unbury_if_needed(c);
            }
            c= clp->next;
        } 

        setmarkerposctg();

        ZincrFlag = 0;
        called_by_merge = 1;  /* otherwise there is a popup */
        move_selected(clone->ctg, new_ctg, new_x - clone->x);
        clone->y = new_y;

        if (new_ctg == max_contig)
        {
          zero_left_end(localcl.ctg);
        }
    }

    if (currentctg > 0)
    {
        gtk_ctgdisplay(currentctg);
    }

    return 1;
}

/* figoure out how many markers hit this contig by going through all
  the marker contig lists */
void update_ctg_marker_count(int ctg)
{
    MARKER* mrk;
    int mrkmax;
    struct markerctgpos* pos;
    int i;

    contigs[ctg].markers = 0;
    mrkmax = arrayMax(markerdata);
    for (i = 0; i < mrkmax; i++)
    {
        mrk = arrp(markerdata,i,MARKER);
        pos = mrk->pos;
        while (pos)
        {
            if (pos->ctg == ctg)
            {
                contigs[ctg].markers++;
                break;   
            }  
        }
    }   
}

/* Check whether marker is attached to clone. DO NOT use index
    values as they can get temporarily messed up by previous marker
    insertions or deletions */
int marker_attached_to_clone(int clone_idx, char* mrk_name)
{
    int ret = 0;
    CLONE* clp; 
    struct markertop* mrk;

    clp = arrp(acedata,clone_idx,CLONE);
    mrk = clp->marker;
    while (mrk)
    {
        if (0 == strcasecmp(mrk->marker, mrk_name))
        {
            ret = 1;
            break;
        }
        mrk = mrk->nextmarker;
    }
    return ret;
}

void add_marker_by_name(char* mrkname, int clone_idx)
{
    int markerindex;
    struct marker* mkr;

    if(!fppFind(markerdata, mrkname, &markerindex, markerOrder))
    {
        fppInsert(markerdata, mrkname, &markerindex, markerOrder);

        mkr = arrayp(markerdata, markerindex, MARKER);

        safe_strncpy(mkr->marker, mrkname, MARKER_SZ);
        mkr->count = 1;
        mkr->type = markPROBE;   
        mkr->anchor = FALSE;
        mkr->cloneindex = clone_idx; /* first clone attached to this marker */
        mkr->status = NEW;
        mkr->colour = 0;   
        mkr->box = mkr->textbox = mkr->textbox2 = mkr->minicontigbox = 0;
        settime(&mkr->creation_date);
        settime(&mkr->modified_date);
        mkr->nextclone = NULL;
        mkr->remark = NULL;
        mkr->pos = (struct markerctgpos*) messalloc((sizeof(struct markerctgpos)));
        mkr->pos->ctg = arrp(acedata,clone_idx,CLONE)->ctg;
        mkr->pos->pos = calcmarkerctgpos(mkr->pos, markerindex);
        mkr->pos->status = AUTO;

        sortoutmarkerindex(); /* this has to be done quickly because clone marker lists are stale */
        attach_marker_to_clone(clone_idx, markerindex);

        if(graphActivate(g2)) 
        {
            graphDestroy();
        }
        if (markerEditWindow)
        {
            gtk_widget_destroy(markerEditWindow);
        }
    }
    else if (!marker_attached_to_clone(clone_idx, mrkname))
    {
        attach_marker_to_clone(clone_idx, markerindex);
        attach_clone_to_marker(markerindex,clone_idx);
    }
    set_marker_clone_max();
    update_contigs_list(markerindex);
}


void create_mainWindow(CLONE *currclone, int cloneindex)
{
   char TmpStr[15];
   int i;
   /* int argc;
   char argv[2][10]; */
   struct CharList *currCharList;
   struct remark *currRemark;
   struct markertop *currMarker;
   struct GelBandsLine *currGBLine;
   struct fpdata *currFP;

   clone_edit_clone = currclone;

   /*argc = 1;
   sprintf(argv[0], "fpc");
   argv[1][0] = '\0';
   gtk_init(&argc, (char***) &argv);*/
   input_data(currclone, cloneindex);

   mw.Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   clone_edit_window = mw.Window;
   gtk_container_set_border_width(GTK_CONTAINER(mw.Window), BORDER_WIDTH);
   gtk_window_set_title(GTK_WINDOW(mw.Window), ("EditClone"));
   gtk_window_set_policy(GTK_WINDOW(mw.Window), FALSE, FALSE, TRUE); 
   gtk_signal_connect (GTK_OBJECT (mw.Window), "destroy",
		      GTK_SIGNAL_FUNC (destroy_edit_clone_callback), NULL); /* WN 04/04*/

   mw.VBox = gtk_vbox_new(FALSE, 3);
   gtk_widget_show(mw.VBox);
   gtk_container_add(GTK_CONTAINER(mw.Window), mw.VBox);

   mw.HBox1 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox1);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox1, FALSE, FALSE, 0);

   mw.CancelButton = gtk_button_new_with_label("Cancel Clone");
   gtk_widget_show(mw.CancelButton);
   gtk_box_pack_end(GTK_BOX(mw.HBox1), mw.CancelButton, FALSE, FALSE, 0);

   mw.RenameButton = gtk_button_new_with_label("Rename Clone");
   gtk_widget_show(mw.RenameButton);
   gtk_box_pack_end(GTK_BOX(mw.HBox1), mw.RenameButton, FALSE, FALSE, 0);

   mw.HBox2 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox2);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox2, FALSE, FALSE, 0);

   mw.CloneText = gtk_label_new("Clone");
   gtk_widget_show(mw.CloneText);
   gtk_box_pack_start(GTK_BOX(mw.HBox2), mw.CloneText, FALSE, FALSE, 0);

   mw.CloneName = gtk_label_new(localcl.clone);
   gtk_widget_show(mw.CloneName);
   gtk_box_pack_start(GTK_BOX(mw.HBox2), mw.CloneName, FALSE, FALSE, 0);

   mw.HBox3 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox3);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox3, FALSE, FALSE, 0);

   mw.ContigText = gtk_label_new("Contig");
   gtk_widget_show(mw.ContigText);
   gtk_box_pack_start(GTK_BOX(mw.HBox3), mw.ContigText, FALSE, FALSE, 0);

   mw.SpinAdj = (GtkAdjustment*) gtk_adjustment_new(localcl.ctg, 0,
                localmisc.NumCtgsInGenome, 1, 5, 15);
   mw.Contig = gtk_spin_button_new(mw.SpinAdj, 5, 0);
   gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(mw.Contig), FALSE);
   gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(mw.Contig),
                                     GTK_UPDATE_IF_VALID);
   gtk_widget_show(mw.Contig);
   gtk_box_pack_start(GTK_BOX(mw.HBox3), mw.Contig, FALSE, FALSE, 0);

   if (localcl.ctg > 0)
   {
      mw.CloneContigL = gtk_entry_new();
      sprintf(TmpStr, "%d", localcl.x);
      gtk_entry_set_text(GTK_ENTRY(mw.CloneContigL), TmpStr);
      gtk_widget_set_usize(mw.CloneContigL,
                           50 + mw.CloneContigL->style->xthickness,
                           20 + mw.CloneContigL->style->ythickness);
      gtk_widget_show(mw.CloneContigL);
      gtk_box_pack_start(GTK_BOX(mw.HBox3), mw.CloneContigL, FALSE, FALSE, 0);

      mw.CloneContigR = gtk_entry_new();
      sprintf(TmpStr, "%d", localcl.y);
      gtk_entry_set_text(GTK_ENTRY(mw.CloneContigR), TmpStr);
      gtk_widget_set_usize(mw.CloneContigR,
                           50 + mw.CloneContigR->style->xthickness,
                           20 + mw.CloneContigR->style->ythickness);
      gtk_widget_show(mw.CloneContigR);
      gtk_box_pack_start(GTK_BOX(mw.HBox3), mw.CloneContigR, FALSE, FALSE, 0);
   }
   else
   {
      mw.CloneContigL = mw.CloneContigR = NULL;
   }

   /* Create, even if FpName == "", so that box
      will exist for Rename Clone function */
   mw.HBox4 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox4);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox4, FALSE, FALSE, 0);

   if ((strcmp(localcl.fp->fpchar, "") != 0)
       && (strcmp(localcl.fp->fpchar, "   ") != 0))
   {
      mw.FpNameText = gtk_label_new("FpName");
      gtk_widget_show(mw.FpNameText);
      gtk_box_pack_start(GTK_BOX(mw.HBox4), mw.FpNameText, FALSE, FALSE, 0);

      mw.FpName = gtk_label_new(localcl.fp->fpchar);
      gtk_widget_show(mw.FpName);
      gtk_box_pack_start(GTK_BOX(mw.HBox4), mw.FpName, FALSE, FALSE, 0);
   }
   else
   {
      mw.FpName = NULL;
   }

   mw.GBLine = (struct GelBandsLine*) malloc(sizeof(struct GelBandsLine));
   for (currGBLine = mw.GBLine, currFP = localcl.fp; currFP != NULL;
        currGBLine = currGBLine->next, currFP = currFP->next)
   {
      currGBLine->HBox = gtk_hbox_new(FALSE, 4);
      gtk_widget_show(currGBLine->HBox);
      gtk_box_pack_start(GTK_BOX(mw.VBox), currGBLine->HBox, FALSE, FALSE, 0);

      currGBLine->GelText = gtk_label_new("Gel");
      gtk_widget_show(currGBLine->GelText);
      gtk_box_pack_start(GTK_BOX(currGBLine->HBox), currGBLine->GelText, FALSE, FALSE, 0);

      currGBLine->GelName = gtk_label_new(currFP->gelname);
      gtk_widget_show(currGBLine->GelName);
      gtk_box_pack_start(GTK_BOX(currGBLine->HBox), currGBLine->GelName, FALSE, FALSE, 0);

      currGBLine->BandsText = gtk_label_new("Bands");
      gtk_widget_show(currGBLine->BandsText);
      gtk_box_pack_start(GTK_BOX(currGBLine->HBox), currGBLine->BandsText, FALSE, FALSE, 0);

      sprintf(TmpStr, "%d", currFP->b1);
      currGBLine->BandsName1 = gtk_label_new(TmpStr);
      gtk_widget_show(currGBLine->BandsName1);
      gtk_box_pack_start(GTK_BOX(currGBLine->HBox), currGBLine->BandsName1, FALSE, FALSE, 0);

      sprintf(TmpStr, "%d", currFP->b2);
      currGBLine->BandsName2 = gtk_label_new(TmpStr);
      gtk_widget_show(currGBLine->BandsName2);
      gtk_box_pack_start(GTK_BOX(currGBLine->HBox), currGBLine->BandsName2, FALSE, FALSE, 0);

      if (currFP->next != NULL)
      {
         currGBLine->next = (struct GelBandsLine*) malloc(sizeof(struct GelBandsLine));
      }
   }

   mw.Separator1 = gtk_hseparator_new();
   gtk_widget_set_usize (mw.Separator1, 400, 5);
   gtk_box_pack_start (GTK_BOX (mw.VBox), mw.Separator1, FALSE, TRUE, 5);
   gtk_widget_show(mw.Separator1);

   mw.HBox7 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox7);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox7, FALSE, FALSE, 0);

   mw.VSub2Box1 = gtk_vbox_new(FALSE, 4);
   gtk_widget_show(mw.VSub2Box1);
   gtk_box_pack_start(GTK_BOX(mw.HBox7), mw.VSub2Box1, FALSE, FALSE, 0);

   mw.RemarksText = gtk_label_new("Remarks");
   gtk_widget_show(mw.RemarksText);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box1), mw.RemarksText, FALSE, FALSE, 0);

   mw.RemarksScroll = gtk_scrolled_window_new(NULL, NULL);
   gtk_widget_show(mw.RemarksScroll);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box1), mw.RemarksScroll, TRUE, TRUE, 0);
   gtk_widget_set_usize(mw.RemarksScroll, 189, 92);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(mw.RemarksScroll),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

   mw.RemarksTextView = gtk_text_view_new();
   gtk_widget_show(mw.RemarksTextView);
   gtk_container_add(GTK_CONTAINER(mw.RemarksScroll), mw.RemarksTextView);
   gtk_widget_set_usize(mw.RemarksTextView, -2, 90);
   gtk_text_view_set_editable(GTK_TEXT_VIEW(mw.RemarksTextView), TRUE);

   for (currRemark = localcl.remark; currRemark != NULL; currRemark = currRemark->next)
   {
      append_attached_remarks(mw.RemarksTextView, currRemark->message);
   }

   mw.MarkersName = gtk_label_new("Markers");
   gtk_widget_show(mw.MarkersName);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box1), mw.MarkersName, FALSE, FALSE, 0);

   mw.MarkersPickToggle = gtk_toggle_button_new_with_label
                          ("Pick from Contig Display");
   gtk_widget_show(mw.MarkersPickToggle);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box1), mw.MarkersPickToggle, FALSE,
                      FALSE, 0);

   mw.MarkersScroll = gtk_scrolled_window_new(NULL, NULL);
   gtk_widget_show(mw.MarkersScroll);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box1), mw.MarkersScroll, TRUE, TRUE, 0);
   gtk_widget_set_usize(mw.MarkersScroll, 189, 92);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(mw.MarkersScroll),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

   mw.MarkersTextView = gtk_text_view_new();
   gtk_widget_show(mw.MarkersTextView);
   gtk_container_add(GTK_CONTAINER(mw.MarkersScroll), mw.MarkersTextView);
   gtk_widget_set_usize(mw.MarkersTextView, -2, 90);
   gtk_text_view_set_editable(GTK_TEXT_VIEW(mw.MarkersTextView), TRUE);

   for (currMarker = localcl.marker; currMarker != NULL; currMarker = currMarker->nextmarker)
   {
      append_attached_remarks(mw.MarkersTextView, currMarker->marker);
   }

   mw.Separator2 = gtk_hseparator_new();
   gtk_widget_set_usize (mw.Separator2, 400, 5);
   gtk_box_pack_start (GTK_BOX (mw.VBox), mw.Separator2, FALSE, TRUE, 5);

   mw.VSub2Box2 = gtk_vbox_new(FALSE, 4);
   gtk_widget_show(mw.VSub2Box2);
   gtk_box_pack_start(GTK_BOX(mw.HBox7), mw.VSub2Box2, FALSE, FALSE, 0);

   mw.FpRemarksText = gtk_label_new("FP Remarks");
   gtk_widget_show(mw.FpRemarksText);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box2), mw.FpRemarksText, FALSE, FALSE, 0);

   mw.FpRemarksScroll = gtk_scrolled_window_new(NULL, NULL);
   gtk_widget_show(mw.FpRemarksScroll);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box2), mw.FpRemarksScroll, TRUE, TRUE, 0);
   gtk_widget_set_usize(mw.FpRemarksScroll, 189, 92);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(mw.FpRemarksScroll),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

   mw.FpRemarksTextView = gtk_text_view_new();
   gtk_widget_show(mw.FpRemarksTextView);
   gtk_container_add(GTK_CONTAINER(mw.FpRemarksScroll), mw.FpRemarksTextView);
   gtk_widget_set_usize(mw.FpRemarksTextView, -2, 90);
   gtk_text_view_set_editable(GTK_TEXT_VIEW(mw.FpRemarksTextView), TRUE);

   for (currRemark = localcl.fp_remark; currRemark != NULL; currRemark = currRemark->next)
   {
      append_attached_remarks(mw.FpRemarksTextView, currRemark->message);
   }

   mw.BuriedClonesText = gtk_label_new("Buried Clones");
   gtk_widget_show(mw.BuriedClonesText);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box2), mw.BuriedClonesText, FALSE, FALSE, 0);

   mw.BuriedClonesPickToggle= gtk_toggle_button_new_with_label("Pick from Contig Display");
   gtk_widget_show(mw.BuriedClonesPickToggle);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box2), mw.BuriedClonesPickToggle, FALSE, FALSE, 0);

   mw.BuriedClonesScroll = gtk_scrolled_window_new(NULL, NULL);
   gtk_widget_show(mw.BuriedClonesScroll);
   gtk_box_pack_start(GTK_BOX(mw.VSub2Box2), mw.BuriedClonesScroll, TRUE, TRUE, 0);
   gtk_widget_set_usize(mw.BuriedClonesScroll, 189, 92);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(mw.BuriedClonesScroll),
                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

   mw.BuriedClonesTextView = gtk_text_view_new();
   gtk_widget_show(mw.BuriedClonesTextView);
   gtk_container_add(GTK_CONTAINER(mw.BuriedClonesScroll),
                     mw.BuriedClonesTextView);
   gtk_widget_set_usize(mw.BuriedClonesTextView, -2, 90);
   gtk_text_view_set_editable(GTK_TEXT_VIEW(mw.BuriedClonesTextView), TRUE);

   currCharList = localmisc.BuriedClones;
   for (i = 0; i < localmisc.NumBuriedClones; i++)
   {
      append_attached_remarks(mw.BuriedClonesTextView, currCharList->name);
      currCharList = currCharList->next;
   }


   mw.Separator2 = gtk_hseparator_new();
   gtk_widget_set_usize (mw.Separator2, 400, 5);
   gtk_box_pack_start (GTK_BOX (mw.VBox), mw.Separator2, FALSE, TRUE, 5);
   gtk_widget_show(mw.Separator2);

   mw.HBox8 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox8);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox8, FALSE, FALSE, 0);

   mw.ParentName = gtk_label_new("Parent");
   gtk_widget_show(mw.ParentName);
   gtk_box_pack_start(GTK_BOX(mw.HBox8), mw.ParentName, FALSE, FALSE, 0);

   strcpy(TmpStr, "");
   if (localcl.parent >= 0)
   {
      strcpy(TmpStr, localcl.match);   // arrp(acedata, localcl.parent, CLONE)->clone);
   }

   mw.ParentText = gtk_entry_new();
   gtk_entry_set_text(GTK_ENTRY(mw.ParentText), TmpStr);
   gtk_widget_show(mw.ParentText);
   gtk_box_pack_start(GTK_BOX(mw.HBox8), mw.ParentText, FALSE, FALSE, 0);

   mw.Separator3 = gtk_hseparator_new();
   gtk_widget_set_usize (mw.Separator3, 400, 5);
   gtk_box_pack_start (GTK_BOX (mw.VBox), mw.Separator3, FALSE, TRUE, 5);
   gtk_widget_show(mw.Separator3);

   mw.HBox9 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox9);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox9, FALSE, FALSE, 0);

   mw.VSub3Box1 = gtk_vbox_new(FALSE, 4);
   gtk_widget_show(mw.VSub3Box1);
   gtk_box_pack_start(GTK_BOX(mw.HBox9), mw.VSub3Box1, TRUE, TRUE, 0);

   mw.CloneTypeText = gtk_label_new("Clone Type");
   gtk_widget_show(mw.CloneTypeText);
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box1), mw.CloneTypeText, FALSE, FALSE, 0);

   mw.CloneTypeOptMenu = gtk_option_menu_new();
   gtk_widget_show(mw.CloneTypeOptMenu);
   mw.CloneTypeMenu = gtk_menu_new();
   gtk_option_menu_set_menu(GTK_OPTION_MENU(mw.CloneTypeOptMenu),
                            mw.CloneTypeMenu);
   strcpy(mw.CloneTypeAry[0], clonetype[0]);
   strcpy(mw.CloneTypeAry[1], clonetype[1]);
   strcpy(mw.CloneTypeAry[2], clonetype[2]);
   strcpy(mw.CloneTypeAry[3], clonetype[3]);
   strcpy(mw.CloneTypeAry[4], clonetype[4]);
   strcpy(mw.CloneTypeAry[5], clonetype[5]);
   strcpy(mw.CloneTypeAry[6], clonetype[6]);
   for (i = 0; i < 7; i++)
   {
      mw.CloneTypeMIAry[i] = gtk_menu_item_new_with_label(mw.CloneTypeAry[i]);
      gtk_menu_append(GTK_MENU(mw.CloneTypeMenu), mw.CloneTypeMIAry[i]);
      if (localcl.class == i)
      {
         gtk_option_menu_set_history(GTK_OPTION_MENU(mw.CloneTypeOptMenu), i);
      }
   }
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box1), mw.CloneTypeOptMenu, TRUE, TRUE, 0);

   mw.VSub3Box2 = gtk_vbox_new(FALSE, 4);
   gtk_widget_show(mw.VSub3Box2);
   gtk_box_pack_start(GTK_BOX(mw.HBox9), mw.VSub3Box2, TRUE, TRUE, 0);

   mw.ShotgunTypeText = gtk_label_new("Shotgun Type");
   gtk_widget_show(mw.ShotgunTypeText);
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box2), mw.ShotgunTypeText, FALSE,
                      FALSE, 0);

   mw.ShotgunTypeOptMenu = gtk_option_menu_new();
   mw.ShotgunTypeMenu = gtk_menu_new();
   gtk_option_menu_set_menu(GTK_OPTION_MENU(mw.ShotgunTypeOptMenu),
                            mw.ShotgunTypeMenu);
   strcpy(mw.ShotgunTypeAry[0], seqtype[0]);
   strcpy(mw.ShotgunTypeAry[1], seqtype[1]);
   strcpy(mw.ShotgunTypeAry[2], seqtype[2]);
   strcpy(mw.ShotgunTypeAry[3], seqtype[3]);
   strcpy(mw.ShotgunTypeAry[4], seqtype[4]);
   strcpy(mw.ShotgunTypeAry[5], seqtype[5]);
   for (i = 0; i < 6; i++)
   {
      mw.ShotgunTypeMIAry[i]=gtk_menu_item_new_with_label(mw.ShotgunTypeAry[i]);
      gtk_menu_append(GTK_MENU(mw.ShotgunTypeMenu), mw.ShotgunTypeMIAry[i]);
   }
   gtk_option_menu_set_history(GTK_OPTION_MENU(mw.ShotgunTypeOptMenu),
                               localcl.seqtype);
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box2), mw.ShotgunTypeOptMenu,
                      TRUE, TRUE, 0);

   mw.VSub3Box3 = gtk_vbox_new(FALSE, 4);
   gtk_widget_show(mw.VSub3Box3);
   gtk_box_pack_start(GTK_BOX(mw.HBox9), mw.VSub3Box3, TRUE, TRUE, 0);

   mw.StatusText = gtk_label_new("Status");
   gtk_widget_show(mw.StatusText);
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box3), mw.StatusText, FALSE, FALSE, 0);

   mw.StatusOptMenu = gtk_option_menu_new();
   gtk_widget_show(mw.StatusOptMenu);
   mw.StatusMenu = gtk_menu_new();
   gtk_option_menu_set_menu(GTK_OPTION_MENU(mw.StatusOptMenu), mw.StatusMenu);
   strcpy(mw.StatusAry[0], seqstat[0]);
   strcpy(mw.StatusAry[1], seqstat[1]);
   strcpy(mw.StatusAry[2], seqstat[2]);
   strcpy(mw.StatusAry[3], seqstat[3]);
   strcpy(mw.StatusAry[4], seqstat[4]);
   strcpy(mw.StatusAry[5], seqstat[5]);
   strcpy(mw.StatusAry[6], seqstat[6]);
   strcpy(mw.StatusAry[7], seqstat[7]);
   for (i = 0; i < 8; i++)
   {
      mw.StatusMIAry[i] = gtk_menu_item_new_with_label(mw.StatusAry[i]);
      gtk_menu_append(GTK_MENU(mw.StatusMenu), mw.StatusMIAry[i]);
   }
   gtk_option_menu_set_history(GTK_OPTION_MENU(mw.StatusOptMenu), localcl.seqstat);
   gtk_box_pack_start(GTK_BOX(mw.VSub3Box3), mw.StatusOptMenu, TRUE, TRUE, 0);

   mw.Separator4 = gtk_hseparator_new();
   gtk_widget_set_usize (mw.Separator4, 400, 5);
   gtk_box_pack_start (GTK_BOX (mw.VBox), mw.Separator4, FALSE, TRUE, 5);
   gtk_widget_show(mw.Separator4);

   mw.HBox10 = gtk_hbox_new(FALSE, 4);
   gtk_widget_show(mw.HBox10);
   gtk_box_pack_start(GTK_BOX(mw.VBox), mw.HBox10, FALSE, FALSE, 0);

   mw.AcceptButton = gtk_button_new_with_label("Accept Edit");
   gtk_widget_show(mw.AcceptButton);
   gtk_box_pack_start(GTK_BOX(mw.HBox10), mw.AcceptButton, FALSE, FALSE, 0);

   mw.RejectButton = gtk_button_new_with_label("Reject Edit");
   gtk_widget_show(mw.RejectButton);
   gtk_box_pack_start(GTK_BOX(mw.HBox10), mw.RejectButton, FALSE, FALSE, 0);

   mw.HelpButton = gtk_button_new_with_label("Help");
   gtk_widget_show(mw.HelpButton);
   gtk_box_pack_end(GTK_BOX(mw.HBox10), mw.HelpButton, FALSE, FALSE, 0);

   gtk_signal_connect(GTK_OBJECT(mw.Window), "delete_event",
                      GTK_SIGNAL_FUNC(on_Window_delete),
                      NULL);
   gtk_signal_connect(GTK_OBJECT(mw.RenameButton), "clicked",
                      GTK_SIGNAL_FUNC(on_RenameButton_clicked),
                      NULL);
   gtk_signal_connect(GTK_OBJECT(mw.CancelButton), "clicked",
                      GTK_SIGNAL_FUNC(on_CancelButton_clicked),
                      currclone);
   gtk_signal_connect(GTK_OBJECT(mw.MarkersPickToggle), "toggled",
                      GTK_SIGNAL_FUNC(on_MarkersPickToggle_toggled),
                      mw.MarkersTextView);
   gtk_signal_connect(GTK_OBJECT(mw.BuriedClonesPickToggle), "toggled",
                      GTK_SIGNAL_FUNC(on_BuriedClonesPickToggle_toggled),
                      mw.BuriedClonesTextView);
   for (i = 0; i < MAX_SELECTIONS; i++)
   {
      if (mw.ShotgunTypeMIAry[i] != NULL)
      {
         gtk_signal_connect(GTK_OBJECT(mw.ShotgunTypeMIAry[i]), "activate",
                            GTK_SIGNAL_FUNC(on_ShotgunStatusMenuItem_activate),
                            mw.StatusOptMenu);
      }
      if (mw.StatusMIAry[i] != NULL)
      {
         gtk_signal_connect(GTK_OBJECT(mw.StatusMIAry[i]), "activate",
                            GTK_SIGNAL_FUNC(on_ShotgunStatusMenuItem_activate),
                            mw.ShotgunTypeOptMenu);
      }
   }
   gtk_signal_connect(GTK_OBJECT(mw.AcceptButton), "clicked",
                      GTK_SIGNAL_FUNC(on_AcceptButton_clicked),
                      currclone);
   gtk_signal_connect(GTK_OBJECT(mw.RejectButton), "clicked",
                      GTK_SIGNAL_FUNC(on_RejectButton_clicked),
                      NULL);
   gtk_signal_connect(GTK_OBJECT(mw.HelpButton), "clicked",
                      GTK_SIGNAL_FUNC(on_HelpButton_clicked),
                      NULL);

   gtk_widget_show_all(mw.Window);
   gtk_main();
}

void append_attached_remarks(GtkWidget *text, char* Rmk)
{
    GtkTextBuffer* buffer;

    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
    gtk_text_buffer_insert_at_cursor(buffer,Rmk,-1);
    gtk_text_buffer_insert_at_cursor(buffer,"\n",-1);
	
}


void appendMarkerToList(int markerindex){
   MARKER* marker;
   gchar last;
   GtkTextBuffer* buffer;
   GtkTextIter it;

   buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(markersTextview));

   if (markerindex < 0) { /* cari 29 june 04 */
      printf("Warning: marker index less than 0\n");
      return;
   }
   /* See if we need to insert a newline*/
   gtk_text_buffer_get_end_iter(buffer,&it);
   gtk_text_iter_backward_char(&it);
   last = gtk_text_iter_get_char(&it);
   if(last != '\n')
      gtk_text_buffer_insert_at_cursor(buffer,"\n",-1);

   marker = arrp(markerdata, markerindex, MARKER);
   gtk_text_buffer_insert_at_cursor(buffer,marker->marker,-1);
   gtk_text_buffer_insert_at_cursor(buffer,"\n",-1);
}

